/**
 * @file lv_demo_music.c
 *
 */

/*********************
 *      INCLUDES
 *********************/
#include "lv_demo_music.h"

#if LV_USE_DEMO_MUSIC

#include "../../../ui/ui.h"
#include "lv_demo_music_main.h"
#include "lv_demo_music_list.h"
#include <pthread.h>
#include <time.h>
#include <errno.h>  

#if LV_DEMO_MUSIC_AUTO_PLAY && LV_USE_PERF_MONITOR
    #include "../../lvgl_private.h"
#endif

/*********************
 *      DEFINES
 *********************/

/**********************
 *      TYPEDEFS
 **********************/

/**********************
 *  STATIC PROTOTYPES
 **********************/
#if LV_DEMO_MUSIC_AUTO_PLAY
    static void auto_step_cb(lv_timer_t * timer);
#endif

/**********************
 *  STATIC VARIABLES
 **********************/
static lv_obj_t * ctrl;
static lv_obj_t * list;
lv_obj_t *ui_ImgButtonMusicToDet;
// 确保只有extern声明，没有定义
extern uint32_t spectrum_i;
extern uint32_t spectrum_i_pause;
extern bool music_flag;


/*************************************************** 这些要直接获取对应歌曲的信息，用命令**************************************   */ 
char  title_list[MAX_NUM][50] = {
    "手写的从前.mp3",
    "Need a Better Future",
    "Vibrations",
};


static const char * artist_list[] = {
    "卢精诚",
    "叶恨水",
    "任子墨",
};

static const char * genre_list[] = {
    "卢精诚 - 2010",
    "叶恨水 - 2016",
    "任子墨 - 2020",
};


uint32_t time_list[MAX_NUM] = {
    1 * 60 + 14,
    2 * 60 + 26,
    1 * 60 + 54,
};

int time_index=0;

/**********************
 *      MACROS
 **********************/

char cur_time_list[MAX_NUM][6]; // 记录歌曲总时长

// 解析mplayer响应的函数
void parse_music_info_response(int song_num, const char *response)
{
    // 安全检查当前索引
    if(song_num < 0 || song_num >= MAX_NUM) {
        printf("错误: song_num=%d 超出范围!\n", song_num);
        return;
    }

    printf("update mplayer info!\n");
    
    // 使用 ID_LENGTH 而不是 ANS_LENGTH
    if (strncmp(response, "ID_LENGTH=", 10) == 0) 
    {
        float total_seconds = atof(response + 10);
        format_time(total_seconds, cur_time_list[song_num]);
        printf("歌曲总时长: %s\n", cur_time_list[song_num]);
    }
    // 使用 ID_FILENAME 而不是 ANS_FILENAME
    else if (strncmp(response, "ID_FILENAME=", 12) == 0) 
    {
        const char *full_path = response + 12;
        
        // 提取文件名（去掉路径）
        const char *filename = strrchr(full_path, '/');
        if(filename) filename++;
        else filename = full_path;
        
        strncpy(title_list[song_num], filename, 50 - 1);
        title_list[song_num][49] = '\0';
        
        char *pos = strstr(title_list[song_num], ".mp3");
        if(pos != NULL) 
        {
            *pos = '\0';
        }
        printf("歌曲名字: %s\n", title_list[song_num]);
    }
}

void music_info_init(void)
{
    char music_path[512] = {0};
    char music_name[128] = {0};
    char command[1024] = {0};
    
    // 初始化数组
    for(int i = 0; i < MAX_NUM; i++) {
        strcpy(title_list[i], "Unknown");
        strcpy(cur_time_list[i], "00:00");
    }
    
    for(int i = 0; i < 3; i++)
    {
        switch(i)
        {
        case 0:
            strcpy(music_name, "writebefore.mp3");
            break;
        case 1:
            strcpy(music_name, "halftoyou.mp3");
            break;
        case 2:
            strcpy(music_name, "heart.mp3");
            break;
        } 
        
        sprintf(music_path, "/mywork/lvgl_3568/lvgl_iPads/%s", music_name);
        sprintf(command, "mplayer -identify -frames 0 -vo null -ao null \"%s\" 2>/dev/null", music_path);

        FILE *fp = popen(command, "r");
        if(fp == NULL) 
        {
            perror("获取信息失败");
            continue;  // 继续处理下一首，不返回
        }

        printf("正在获取歌曲信息: %s\n", music_path);
        
        while(1) 
        {
            char response[1024] = {0};
            char *ret = fgets(response, sizeof(response), fp);
            if(ret == NULL) break;
            
            // 去除换行符
            response[strcspn(response, "\n")] = 0;
            
            // 解析歌曲信息
            time_index=i;
            parse_music_info_response(time_index, response);
        }
        
        
        pclose(fp);
    }
    printf("歌曲信息获取完成\n");
}



// 添加互斥锁
pthread_mutex_t music_mutex = PTHREAD_MUTEX_INITIALIZER;

// 初始化互斥锁
void init_music_mutex()
{
    pthread_mutex_init(&music_mutex, NULL);
}

// 销毁互斥锁
void destroy_music_mutex()
{
    pthread_mutex_destroy(&music_mutex);
}

// 安全地获取当前视频编号
int get_current_music_num()
{
    int num;
    pthread_mutex_lock(&music_mutex);
    num = current_num;
    pthread_mutex_unlock(&music_mutex);
    return num;
}

// 安全地设置当前视频编号
void set_current_music_num(int num)
{
    pthread_mutex_lock(&music_mutex);
    current_num = num;
    pthread_mutex_unlock(&music_mutex);
}

// void lv_demo_music_close(void)
// {
//     // 停止并删除定时器
//     if(sec_counter_timer) {
//         lv_timer_del(sec_counter_timer);
//         sec_counter_timer = NULL;
//     }
    
//     // 停止动画
//     lv_anim_delete(spectrum_obj, spectrum_anim_cb);
//     lv_anim_delete(NULL, start_anim_cb);
    
//     // 停止音乐播放
//     if(music_flag) {
//         safe_kill_mplayer();
//         if(tid) {
//             pthread_join(tid, NULL);
//             tid = 0;
//         }
//         music_flag = false;
//     }
    
//     // 重置状态变量
//     playing = false;
//     spectrum_i = 0;
//     spectrum_i_pause = 0;
//     time_act = 0;
//     start_anim = false;
    
//     // 销毁互斥锁
//     destroy_music_mutex();
// }


void lv_demo_music_close(void)
{
    // 停止并删除定时器
    if(sec_counter_timer) {
        lv_timer_del(sec_counter_timer);
        sec_counter_timer = NULL;
    }
    
    // 停止动画
    if(spectrum_obj) {  // 检查对象是否还存在
        lv_anim_delete(spectrum_obj, spectrum_anim_cb);
    }
    lv_anim_delete(NULL, start_anim_cb);
    
    // 停止音乐播放
    if(music_flag) {
        safe_kill_mplayer();
        if(tid) {
            // 直接尝试分离线程，不等待
            int ret = pthread_detach(tid);
            if(ret != 0) {
                printf("Warning: Failed to detach music thread\n");
            }
            tid = 0;
        }
        music_flag = false;
    }else {
        // 即使没有播放音乐，也确保释放音频设备
        audio_device_release();
    }
    
    // 重置状态变量
    playing = false;
    spectrum_i = 0;
    spectrum_i_pause = 0;
    time_act = 0;
    start_anim = false;
    lv_obj_del(list);
    
    // 销毁互斥锁
    destroy_music_mutex();
}

// 屏幕切换定时器回调函数
static void screen_change_timer_cb(lv_timer_t *t)
{
    _ui_screen_change(&ui_ScreenDestop, LV_SCR_LOAD_ANIM_FADE_ON, 100, 0, &ui_ScreenDestop_screen_init);
    lv_timer_del(t);  // 删除定时器
}

static void ui_event_ImgButtonMusicToDet_cb(lv_event_t *e)
{
    lv_event_code_t event_code = lv_event_get_code(e);
    lv_obj_t * target = lv_event_get_target(e);
    if(event_code == LV_EVENT_CLICKED) 
    {
        lv_demo_music_close();

        lv_timer_create(screen_change_timer_cb, 100, NULL);
        // _ui_screen_change(&ui_ScreenDestop, LV_SCR_LOAD_ANIM_FADE_ON, 100, 0, &ui_ScreenDestop_screen_init);
        
    }
}


void audio_device_release(void) 
{
    // 终止所有mplayer进程
    system("pkill -TERM mplayer");
    system("pkill -KILL mplayer");
    
    // 等待进程完全终止
    usleep(200000); // 200ms延迟
    
    // 释放音频设备
    system("fuser -k /dev/snd/pcmC0D0p >/dev/null 2>&1");
    system("fuser -k /dev/snd/controlC0 >/dev/null 2>&1");
}

bool audio_device_check(void) 
{
    FILE *fp;
    char result[128];
    
    // 检查音频设备是否存在
    fp = popen("ls /dev/snd/pcmC0D0p 2>/dev/null", "r");
    if (fp == NULL || fgets(result, sizeof(result), fp) == NULL) {
        if (fp) pclose(fp);
        return false;
    }
    pclose(fp);
    
    // 检查音频设备是否被占用
    fp = popen("fuser /dev/snd/pcmC0D0p 2>/dev/null", "r");
    if (fp != NULL && fgets(result, sizeof(result), fp) != NULL) {
        pclose(fp);
        return false;
    }
    if (fp) pclose(fp);
    
    return true;
}

/**********************
 *   GLOBAL FUNCTIONS
 **********************/

void lv_demo_music(void)
{
    lv_obj_set_style_bg_color(lv_screen_active(), lv_color_hex(0x343247), 0);

    init_music_mutex(); // 初始化互斥锁（自定义）
    music_info_init();  // 获取歌曲信息（自定义）
    list = lv_demo_music_list_create(lv_screen_active()); // 上拉列表
    ctrl = lv_demo_music_main_create(lv_screen_active()); // 播放界面

    // 新增返回按钮
    ui_ImgButtonMusicToDet = lv_imagebutton_create(ui_ScreenMusic);
    lv_imagebutton_set_src(ui_ImgButtonMusicToDet, LV_IMAGEBUTTON_STATE_RELEASED, NULL, &ui_img_last3_png, NULL);
    lv_imagebutton_set_src(ui_ImgButtonMusicToDet, LV_IMAGEBUTTON_STATE_PRESSED, NULL, &ui_img_last2_png, NULL);
    lv_obj_set_height(ui_ImgButtonMusicToDet, 50);
    lv_obj_set_width(ui_ImgButtonMusicToDet, LV_SIZE_CONTENT);   /// 1
    lv_obj_set_x(ui_ImgButtonMusicToDet, 474);
    lv_obj_set_y(ui_ImgButtonMusicToDet, -267);
    lv_obj_set_align(ui_ImgButtonMusicToDet, LV_ALIGN_CENTER);

    lv_obj_add_event_cb(ui_ImgButtonMusicToDet, ui_event_ImgButtonMusicToDet_cb, LV_EVENT_ALL, NULL);
    
#if LV_DEMO_MUSIC_AUTO_PLAY
    lv_timer_create(auto_step_cb, 1000, NULL);
#endif
}

const char * lv_demo_music_get_title(uint32_t track_id)
{
    if(track_id >= sizeof(title_list) / sizeof(title_list[0])) return NULL;
    return title_list[track_id];
}

const char * lv_demo_music_get_artist(uint32_t track_id)
{
    if(track_id >= sizeof(artist_list) / sizeof(artist_list[0])) return NULL;
    return artist_list[track_id];
}

const char * lv_demo_music_get_genre(uint32_t track_id)
{
    if(track_id >= sizeof(genre_list) / sizeof(genre_list[0])) return NULL;
    return genre_list[track_id];
}

uint32_t lv_demo_music_get_track_length(uint32_t track_id)
{
    if(track_id >= sizeof(time_list) / sizeof(time_list[0])) return 0;
    return time_list[track_id];
}



/**********************
 *   STATIC FUNCTIONS
 **********************/

#if LV_DEMO_MUSIC_AUTO_PLAY
static void auto_step_cb(lv_timer_t * t)
{
    LV_UNUSED(t);
    static uint32_t state = 0;

#if LV_DEMO_MUSIC_LARGE
    const lv_font_t * font_small = &lv_font_montserrat_22;
    const lv_font_t * font_large = &lv_font_montserrat_32;
#else
    const lv_font_t * font_small = &lv_font_montserrat_12;
    const lv_font_t * font_large = &lv_font_montserrat_16;
#endif

    switch(state) {
        case 5:
            lv_demo_music_album_next(true);
            break;

        case 6:
            lv_demo_music_album_next(true);
            break;
        case 7:
            lv_demo_music_album_next(true);
            break;
        case 8:
            lv_demo_music_play(0);
            break;
#if LV_DEMO_MUSIC_SQUARE || LV_DEMO_MUSIC_ROUND
        case 11:
            lv_obj_scroll_by(ctrl, 0, -LV_VER_RES, LV_ANIM_ON);
            break;
        case 13:
            lv_obj_scroll_by(ctrl, 0, -LV_VER_RES, LV_ANIM_ON);
            break;
#else
        case 12:
            lv_obj_scroll_by(ctrl, 0, -LV_VER_RES, LV_ANIM_ON);
            break;
#endif
        case 15:
            lv_obj_scroll_by(list, 0, -300, LV_ANIM_ON);
            break;
        case 16:
            lv_obj_scroll_by(list, 0, 300, LV_ANIM_ON);
            break;
        case 18:
            lv_demo_music_play(1);
            break;
        case 19:
            lv_obj_scroll_by(ctrl, 0, LV_VER_RES, LV_ANIM_ON);
            break;
#if LV_DEMO_MUSIC_SQUARE || LV_DEMO_MUSIC_ROUND
        case 20:
            lv_obj_scroll_by(ctrl, 0, LV_VER_RES, LV_ANIM_ON);
            break;
#endif
        case 30:
            lv_demo_music_play(2);
            break;
        case 40: {
                lv_obj_t * bg = lv_layer_top();
                lv_obj_set_style_bg_color(bg, lv_color_hex(0x6f8af6), 0);
                lv_obj_set_style_text_color(bg, lv_color_white(), 0);
                lv_obj_set_style_bg_opa(bg, LV_OPA_COVER, 0);
                lv_obj_fade_in(bg, 400, 0);
                lv_obj_t * dsc = lv_label_create(bg);
                lv_obj_set_style_text_font(dsc, font_small, 0);
                lv_label_set_text(dsc, "The average FPS is");
                lv_obj_align(dsc, LV_ALIGN_TOP_MID, 0, 90);

                lv_obj_t * num = lv_label_create(bg);
                lv_obj_set_style_text_font(num, font_large, 0);
#if LV_USE_PERF_MONITOR
                lv_display_t * disp = lv_display_get_default();
                const lv_sysmon_perf_info_t * info = lv_subject_get_pointer(&disp->perf_sysmon_backend.subject);
                lv_label_set_text_fmt(num, "%" LV_PRIu32, info->calculated.fps_avg_total);
#endif
                lv_obj_align(num, LV_ALIGN_TOP_MID, 0, 120);

                lv_obj_t * attr = lv_label_create(bg);
                lv_obj_set_style_text_align(attr, LV_TEXT_ALIGN_CENTER, 0);
                lv_obj_set_style_text_font(attr, font_small, 0);
#if LV_DEMO_MUSIC_SQUARE || LV_DEMO_MUSIC_ROUND
                lv_label_set_text(attr, "Copyright 2020 LVGL Kft.\nwww.lvgl.io | lvgl@lvgl.io");
#else
                lv_label_set_text(attr, "Copyright 2020 LVGL Kft. | www.lvgl.io | lvgl@lvgl.io");
#endif
                lv_obj_align(attr, LV_ALIGN_BOTTOM_MID, 0, -10);
                break;
            }
        case 41:
            lv_screen_load(lv_obj_create(NULL));
            lv_demo_music_pause();
            break;
    }
    state++;
}

#endif /*LV_DEMO_MUSIC_AUTO_PLAY*/

#endif /*LV_USE_DEMO_MUSIC*/
